﻿//Copyright (c) 2009-2010, Andreas Grünwald
//All rights reserved.

using System;
using System.Collections.ObjectModel;

namespace yaTDL.Core
{
    /// <summary>
    /// The base class for every class that has a Identifier (e.g. <see cref="Task"/>, <see cref="Project"/>).
    /// </summary>
    public class ObjectWithId:NotifyObject
    {
        #region Fields

        private string _id = "";
        private int _indent = 0;
        private int _collapsed = 0;
        private int _order = 0;
        private string _userId = "";        

        /// <summary>
        /// A string that is put in front of every Identifier created by CreateID().
        /// </summary>
        private string idPrefix;

        #endregion

        #region Events

        public event EventHandler<IdChangedEventArgs> IdChanged;

        #endregion

        #region Properties

        /// <summary>
        /// The Identifier of an object that inherits from ObjectWithId
        /// </summary>
        public string Id
        {
            get { return _id; }
            set
            {
                if (value != _id)
                {
                    string oldId = _id;
                    _id = value;
                    OnIdChanged(oldId);                    
                }
            }
        }

        /// <summary>
        /// Indicates when the Task/Project has been changed the last time.
        /// </summary>
        public DateTime LastEdited { get; set; }

        public string UserId
        {
            get { return _userId; }
            set
            {
                if (value != _userId)
                {                    
                    _userId = value;
                    RaisePropertyChanged("UserId");
                }
            }
        }

        public int Indent
        {
            get { return _indent; }
            set
            {
                if (value != _indent)
                {                    
                    _indent = value;
                    RaisePropertyChanged("Indent");
                }
            }
        }        

        public int Collapsed
        {
            get { return _collapsed; }
            set
            {
                if (value != _collapsed)
                {
                    _collapsed = value;
                    RaisePropertyChanged("Collapsed");
                }              
            }
        }

        public int Order
        {
            get { return _order; }
            set
            {
                if (value != _order)
                {
                    _order = value;
                    RaisePropertyChanged("Order");
                }
            }
        }

        #endregion


        #region Constructor(s)

        /// <summary>
        /// Initializes a new instance of ObjectWithId.
        /// </summary>
        /// <param name="idPrefix">The string that will be put in front of every Id created by CreateID().</param>
        public ObjectWithId(string idPrefix)
        {
            this.idPrefix = idPrefix;
                     
            CreateId();
        }


        #endregion


        #region Protected Methods
        
        
        /// <summary>
        /// Raises the IdChanged event.
        /// </summary>
        protected void OnIdChanged(string oldId)
        {
            RaisePropertyChanged("Id");
            if (IdChanged != null)
            {
                IdChanged(this, new IdChangedEventArgs(oldId));
            }
        }

        protected override void RaisePropertyChanged(string propertyName)
        {
            LastEdited = DateTime.Now;
            base.RaisePropertyChanged(propertyName);
        }

        /// <summary>
        /// Creates a new Identifier for the object and saves it to Id.
        /// The Id consists of the value of idPrefix followed by a Guid.
        /// </summary>
        protected void CreateId()
        {
            Id = idPrefix + Guid.NewGuid().ToString();
        }
        
        #endregion


        #region Public Methods

        public override string ToString()
        {
            string result = "Id: " + Id + " - ";
            result += "UserId: " + UserId + " - ";
            result += "Indent: " + Indent.ToString() + " - ";
            result += "Collapsed: " + Collapsed.ToString() + " - ";
            result += "Order: " + Order.ToString() + ";";

            return result;
        }

        public virtual Collection<PropertyChange> Diff(ObjectWithId otherObject)
        {
            Collection<PropertyChange> result = new Collection<PropertyChange>();

            if (this.Collapsed != otherObject.Collapsed)
            { result.Add(new PropertyChange() { PropertyName = "Collapsed", Value1 = this.Collapsed, Value2 = otherObject.Collapsed }); }

            if (this.Id != otherObject.Id)
            { result.Add(new PropertyChange() { PropertyName = "Id", Value1 = this.Id, Value2 = otherObject.Id }); }

            if (this.Indent != otherObject.Indent)
            { result.Add(new PropertyChange() { PropertyName = "Indent", Value1 = this.Indent, Value2 = otherObject.Indent }); }

            if (this.Order != otherObject.Order)
            { result.Add(new PropertyChange() { PropertyName = "Order", Value1 = this.Order, Value2 = otherObject.Order }); }

            if (this.UserId != otherObject.UserId)
            { result.Add(new PropertyChange() { PropertyName = "UserId", Value1 = this.UserId, Value2 = otherObject.UserId }); }


            return result;
        }

        #endregion
    }
}
